using System;

namespace Picnic.Spec.Console.ExceptionWriters
{
	public abstract class AbstractExceptionWriter : IConsoleExceptionWriter
	{
		private readonly ConsoleColor _color;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:System.Object"/> class.
		/// </summary>
		protected AbstractExceptionWriter(ConsoleColor color = ConsoleColor.Red)
		{
			_color = color;
		}

		/// <summary>
		/// Determines is writer can write specified exception.
		/// </summary>
		public abstract bool CanWrite(Exception exception);

		/// <summary>
		/// Writes exception using specified console writer.
		/// </summary>
		public void Write(IConsole console, Exception exception)
		{
			console.SetColor(_color);
			WriteException(console, exception);
			console.UndoColor();
		}

		protected abstract void WriteException(IConsole console, Exception exception);
	}

	public abstract class AbstractExceptionWriter<T> : AbstractExceptionWriter where T : Exception
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="T:System.Object"/> class.
		/// </summary>
		protected AbstractExceptionWriter(ConsoleColor color = ConsoleColor.Red) : base(color) { }

		/// <summary>
		/// Determines is writer can write specified exception.
		/// </summary>
		public override bool CanWrite(Exception exception)
		{
			return exception is T;
		}

		protected override void WriteException(IConsole console, Exception exception)
		{
			WriteException(console, exception as T);
		}

		protected abstract void WriteException(IConsole console, T exception);
	}
}